/*
 * 部分参考RT-Thread
 * Copyright (c) 2006-2018, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
*/
#ifndef __DEVICE_H__
#define __DEVICE_H__

#include "type.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * 设备标志定义
 */
#define ETF_DEVICE_FLAG_DEACTIVATE      0x000           /**< 设备未初始化 */

#define ETF_DEVICE_FLAG_RDONLY          0x001           /**< 只读 */
#define ETF_DEVICE_FLAG_WRONLY          0x002           /**< 只写 */
#define ETF_DEVICE_FLAG_RDWR            0x003           /**< 读写 */

#define ETF_DEVICE_FLAG_REMOVABLE       0x004           /**< 可移除设备 */
#define ETF_DEVICE_FLAG_STANDALONE      0x008           /**< 独立的设备 */
#define ETF_DEVICE_FLAG_ACTIVATED       0x010           /**< 设备是被激活的 */
#define ETF_DEVICE_FLAG_SUSPENDED       0x020           /**< 设备是挂起的 */
#define ETF_DEVICE_FLAG_STREAM          0x040           /**< 流模式 */

#define ETF_DEVICE_FLAG_INT_RX          0x100           /**< 中断模式接收 */
#define ETF_DEVICE_FLAG_DMA_RX          0x200           /**< DMA模式接收 */
#define ETF_DEVICE_FLAG_INT_TX          0x400           /**< 中断模式发送 */
#define ETF_DEVICE_FLAG_DMA_TX          0x800           /**< DMA模式发送 */

#define ETF_DEVICE_OFLAG_CLOSE          0x000           /**< 设备是关闭的 */
#define ETF_DEVICE_OFLAG_RDONLY         0x001           /**< 只读访问 */
#define ETF_DEVICE_OFLAG_WRONLY         0x002           /**< 只写访问 */
#define ETF_DEVICE_OFLAG_RDWR           0x003           /**< 读写访问 */
#define ETF_DEVICE_OFLAG_OPEN           0x008           /**< 设备是打开的 */
#define ETF_DEVICE_OFLAG_MASK           0xf0f           /**< 打开标志掩码 */

/**
 * 一般设备指令
 */
#define ETF_DEVICE_CTRL_RESUME          0x01            /**< 恢复设备 */
#define ETF_DEVICE_CTRL_SUSPEND         0x02            /**< 暂停设备 */
#define ETF_DEVICE_CTRL_CONFIG          0x03            /**< 配置设备 */

#define ETF_DEVICE_CTRL_SET_INT         0x10            /**< 设置中断 */
#define ETF_DEVICE_CTRL_CLR_INT         0x11            /**< 清除中断 */
#define ETF_DEVICE_CTRL_GET_INT         0x12            /**< 获取中断状态 */

/**
 * 特殊设备指令
 */
#define ETF_DEVICE_CTRL_CHAR_STREAM     0x10            /**< 字符设备上的流模式 */
#define ETF_DEVICE_CTRL_BLK_GETGEOME    0x10            /**< 获取getgeome信息   */
#define ETF_DEVICE_CTRL_BLK_SYNC        0x11            /**< 将数据刷新到块设备 */
#define ETF_DEVICE_CTRL_BLK_ERASE       0x12            /**< 在块设备上擦除块 */
#define ETF_DEVICE_CTRL_BLK_AUTOREFRESH 0x13            /**< 块设备：进入/退出自动刷新模式 */
#define ETF_DEVICE_CTRL_NETIF_GETMAC    0x10            /**< 获取mac地址 */
#define ETF_DEVICE_CTRL_MTD_FORMAT      0x10            /**< 格式化一个MTD设备 */
#define ETF_DEVICE_CTRL_RTC_GET_TIME    0x10            /**< 获取时间 */
#define ETF_DEVICE_CTRL_RTC_SET_TIME    0x11            /**< 设置时间 */
#define ETF_DEVICE_CTRL_RTC_GET_ALARM   0x12            /**< 获取警报 */
#define ETF_DEVICE_CTRL_RTC_SET_ALARM   0x13            /**< 设置警报 */


/* 定义设备指针类型名 */
typedef struct etf_device *                 etf_device_t;

/**
 * device (I/O) class type
 */
enum etf_device_class_type
{
    ETF_Device_Class_Char = 0,                          /**< character device */
    ETF_Device_Class_Block,                             /**< block device */
    ETF_Device_Class_NetIf,                             /**< net interface */
    ETF_Device_Class_MTD,                               /**< memory device */
    ETF_Device_Class_CAN,                               /**< CAN device */
    ETF_Device_Class_RTC,                               /**< RTC device */
    ETF_Device_Class_Sound,                             /**< Sound device */
    ETF_Device_Class_Graphic,                           /**< Graphic device */
    ETF_Device_Class_I2CBUS,                            /**< I2C bus device */
    ETF_Device_Class_USBDevice,                         /**< USB slave device */
    ETF_Device_Class_USBHost,                           /**< USB host bus */
    ETF_Device_Class_SPIBUS,                            /**< SPI bus device */
    ETF_Device_Class_SPIDevice,                         /**< SPI device */
    ETF_Device_Class_SDIO,                              /**< SDIO bus device */
    ETF_Device_Class_PM,                                /**< PM pseudo device */
    ETF_Device_Class_Pipe,                              /**< Pipe device */
    ETF_Device_Class_Portal,                            /**< Portal device */
    ETF_Device_Class_Timer,                             /**< Timer device */
    ETF_Device_Class_Miscellaneous,                     /**< Miscellaneous device */
    ETF_Device_Class_Sensor,                            /**< Sensor device */
    ETF_Device_Class_Touch,                             /**< Touch device */
    ETF_Device_Class_Unknown                            /**< unknown device */
};


/* 设备操作接口类型 */
struct etf_device_ops{
    /* 设备初始化。再打开设备的时候自动执行。参数：设备句柄、打开标志 */
    etf_err_t               (*init)     (etf_device_t dev);
    /* 打开设备。参数：设备句柄、打开标志 */
    etf_err_t               (*open)     (etf_device_t dev, etf_flag_t flag);
    /* 关闭设备。参数：设备句柄 */
    etf_err_t               (*close)    (etf_device_t dev);
    /* 读设备。参数：设备句柄、读设备寄存器地址、数据存放地址、数据尺寸 */
    etf_size_t              (*read)     (etf_device_t dev, etf_off_t pos, void *buffer, etf_size_t size);
    /* 写设备。参数：设备句柄、写设备寄存器地址、数据存放地址、数据尺寸 */
    etf_size_t              (*write)    (etf_device_t dev, etf_off_t pos, const void *buffer, etf_size_t size);
    /* 控制设备。参数：设备句柄、控制指令、参数 */
    etf_err_t               (*control)  (etf_device_t dev, etf_uint32_t cmd, void *args);
};

/* 定义设备操作接口指针类型 */
typedef struct etf_device_ops *             etf_device_ops_t;


/* 通用设备类型 */
struct etf_device {
    struct etf_object                       parent;                     //对象继承，必须为第一个成员，否则etf_device_find查找设备时返回的地址将不可用

    enum etf_device_class_type              type;                       //设备类型
    etf_uint16_t                            flag;                       //设备标志
    etf_uint16_t                            open_flag;                  //设备打开标志

    etf_uint8_t                             ref_count;                  //设备引用计数(打开计数，关闭时清零)
//    etf_uint8_t                             device_id;                  //设备ID0~255

    /* 设备回调函数接口 */
    etf_err_t               (*rx_indicate)(etf_device_t dev, etf_size_t size);      //接收中断回调函数
    etf_err_t               (*tx_complete)(etf_device_t dev, void *buffer);         //发送完成中断回调函数

    etf_device_ops_t                        ops;                        //设备操作接口指针;

    void                                    *user_data;                 //用户私有数据地址;
};

extern char etf_device_class_type_table[][15];

void etf_device_module_init(void);
etf_err_t etf_device_register(etf_device_t dev, const char *name, etf_uint16_t flags);
etf_err_t etf_device_unregister(etf_device_t dev);
etf_device_t etf_device_find(const char *name);
etf_err_t rt_device_init(etf_device_t dev);
etf_err_t etf_device_open(etf_device_t dev, etf_uint16_t oflag);
etf_err_t etf_device_close(etf_device_t dev);
etf_size_t etf_device_read(etf_device_t dev, etf_off_t pos, void *buffer, etf_size_t size);
etf_size_t etf_device_write(etf_device_t dev, etf_off_t pos, const void *buffer, etf_size_t size);
etf_err_t etf_device_control(etf_device_t dev, etf_uint32_t cmd, void *arg);
etf_err_t etf_device_set_rx_indicate(etf_device_t dev, etf_err_t (*rx_ind)(etf_device_t dev, etf_size_t size));
etf_err_t etf_device_set_tx_complete(etf_device_t dev, etf_err_t (*tx_done)(etf_device_t dev, void *buffer));

#ifdef __cplusplus
}
#endif
 
#endif
 

